<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <ul>
        <li><router-link to="/">Home</router-link></li>
        <li><router-link to="/user/1">User/1</router-link></li>
        <li><router-link to="/user/2">User/2</router-link></li>
        <li><router-link to="/profile/email">/profile/email</router-link></li>
      </ul>
      <router-view></router-view>
    </div>
    <script src="https://unpkg.com/vue@2/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3/dist/vue-router.js"></script>
    <script>
      const Home = {template:'<div>Home</div>'}
      const User = {
        props:['userId'],
        template:`<div>userId:{{userId}}</div>`,
        beforeRouteEnter(to,from,next){
          console.log('beforeRouteEnter',to.path)
          next();
        },
        beforeRouteUpdate(to,from,next){
          console.log('beforeRouteUpdate',from.path,to.path)
          next();
        },
        beforeRouteLeave(to,from,next){
          console.log('beforeRouteLeave',from.path)
          next();
        }
      }
      const Profile = {template:'<div>Profile <router-view></router-view> </div>'}
      const Email = {template:'<div>Email</div>'}
      const Phone = {template:'<div>Phone</div>'}
      const Login = {
        template:`<div><button @click="login">登录</button></div>`,
        methods:{
          login(){
            localStorage.setItem('isLogin','true');
            router.back();
          }
        }
      }
      var routes = [
        //我们称routes配置中的每一个对象为路由记录，路由的记录是可以嵌套的，
        {name:'home',path:'/',component:Home},
        {name:'home',path:'/login',component:Login},
        {
            path:"/user/:userId",
            component:User,
            props:true,
            beforeEnter(to,from,next){//只有匹配上这条路由规则的话才会执行此守卫函数
              console.log('beforeEnter',to.path);
              next();
            }
        },
        {
          name:'profile',
          path:'/profile',
          component:Profile,
          meta:{requireLogin:true},
          children:[
            {
              path:'email',// /profile/email
              component:Email,
            },
            {
              path:'phone',// /profile/phone
              component:Phone
            }
          ]
        },
      ];
      function isLogin(){
        return !!localStorage.getItem('isLogin');//一定会返回一个boolean
      }
      Vue.use(VueRouter);
      var router = new VueRouter({routes});
      var vm = new Vue({
        el: "#app",
        router,
      });
      //监听跳转错误，进行全局捕获
      router.onError((error)=>{
        console.error(error)
      });
      //每一次导航前都会触发,全局的，针对所有的路径跳转都会生效
      router.beforeEach((to,from,next)=>{
        //判断自己和自己的祖先匹配结果中是否需要登录，只要有一个需要登录，就返回true
        let requireLogin = to.matched.some((({meta})=>meta.requireLogin));
        //如果需要登录，并且当前的用户未登录，则跳到登录页去登录
        if(requireLogin && !isLogin()){
          next('/login');
        }else{//否则 如果不需要登录，或者已经 登录了
          next();
        }
        //console.log('beforeEach',to.path)
        //next();//如果后面还有钩子，就调用下一个钩子
      });
      router.beforeResolve((to,from,next)=>{
        //比如说我们想在渲染组件做一些准备工作，比如获取要渲染的数据
        //执行时机是在导航被确认之前，同时所有的组件内守卫和异步组件都已经解析完毕了
        console.log('beforeResolve',to.path)
        next();//如果后面还有钩子，就调用下一个钩子
      });
      router.afterEach((to,from)=>{
        console.log('afterEach',to.path)
      });
    </script>
  </body>
</html>
